<!--
 * @Author: Penk
 * @LastEditors: Penk
 * @LastEditTime: 2022-11-23 02:28:41
 * @FilePath: \web面试题\节流.html
 * @email: 492934056@qq.com
-->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      body {
        width: 100%;
        height: 100vh;
        padding: 20px;
        box-sizing: border-box;
      }
      .moveBox {
        width: 500px;
        height: 200px;
        background-color: antiquewhite;
      }

      .throttle_box .throttle_box_label {
        display: block;
        margin: 30px 0 10px 0;
      }

      .tooltips {
        display: block;
        color: red;
        font-size: 12px;
        margin-top: 2px;
      }
    </style>
  </head>
  <body>
    <h3>这边制作的是一个div，监听器鼠标在div上滑动然后就调用异步方法。</h3>

    <div class="throttle_box">
      <span class="throttle_box_label">不做节流：</span>
      <div id="moveBox1" class="moveBox"></div>
    </div>
    <div class="throttle_box">
      <span class="throttle_box_label">全局标志位isRunning实现节流：</span>
      <div id="moveBox2" class="moveBox"></div>
    </div>
    <div class="throttle_box">
      <span class="throttle_box_label">闭包实现节流：</span>
      <div id="moveBox3" class="moveBox"></div>
    </div>
    <div class="throttle_box">
      <span class="throttle_box_label">闭包实现节流：</span>
      <div id="moveBox4" class="moveBox"></div>
    </div>

    <script>
      var moveBox1 = document.getElementById("moveBox1");
      moveBox1.addEventListener("mousemove", function (e) {
        console.log(`不做节流：e.screenX：${e.screenX}`);
      });

      // 标志位，判断是否运行中...
      // 如果是在运行了，则跳过业务逻辑；
      // 如果不在运行，则将状态改成在运行中，并且在业务逻辑处理完毕后，需要将状态改成不在运行中...
      let isRunning = false;
      var moveBox2 = document.getElementById("moveBox2");
      moveBox2.addEventListener("mousemove", function (e) {
        // 不在运行中
        if (!isRunning) {
          setTimeout(() => {
            console.log(`全局标志位isRunning实现节流：e.screenX：${e.screenX}`);
            // 运行完毕需要关闭正在运行的标志
            isRunning = false;
          }, 500);

          isRunning = true;
        }
      });

      var moveBox3 = document.getElementById("moveBox3");
      moveBox3.addEventListener(
        "mousemove",
        // 改参数是一个函数
        // 应用闭包，返回的函数自带作用域私有变量
        throttle((e) => {
          console.log(`闭包实现节流 input3：e.screenX：${e.screenX}`);
        }, 500)
      );

      var moveBox4 = document.getElementById("moveBox4");
      moveBox4.addEventListener(
        "mousemove",
        // 改参数是一个函数
        // 应用闭包，返回的函数自带作用域私有变量
        // 这里的e，不是事件监听直接给的，是由闭包call带参e
        throttle((e) => {
          console.log(`闭包实现节流 input4：e.screenX：${e.screenX}`);
        }, 500)
      );

      /**
       * @author: Penk
       * @description: 节流函数
       * @param {*} fn
       * @param {*} timeout
       * @return {*}
       */
      function throttle(fn, timeout = 500) {
        let isRunning = false;
        // 这里的event，可以通过.call 传过去到fn参数中
        return function (e) {
          if (!isRunning) {
            setTimeout(() => {
              fn.call(this, e);
              isRunning = false;
            }, timeout);
            isRunning = true;
          }
        };
      }
    </script>
  </body>
</html>
